package laMalinche.AnnotatedRules;

import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import java.util.HashSet;

import laMalinche.rete.rule.ProductionRule;

/**
 * Created by IntelliJ IDEA.
 * User: ranran
 * Date: Aug 13, 2009
 * Time: 10:45:24 PM
 * To change this template use File | Settings | File Templates.
 */
public  class AnnotatedMethodsClass<S> {
    Class<? extends InScopeOf<S>>[] ruleClasses;
    S scope;
    public AnnotatedMethodsClass(S scope, Class<? extends InScopeOf<S>> ... aClass){
       ruleClasses = aClass;
       this.scope =scope;
    }

     public  Set<ProductionRule> getProductionRules(){
          Set<ProductionRule> productionRules = new HashSet<ProductionRule>();
         for (Class<? extends InScopeOf<S>> ruleClass :ruleClasses ){
             productionRules.addAll(getProductionRules(ruleClass));
         }
         return productionRules;
     }

     private  Set<ProductionRule> getProductionRules(Class<? extends InScopeOf<S>> ruleClass){
         Method[] methods = ruleClass.getDeclaredMethods();
         Set<ProductionRule> methodsSet = new HashSet<ProductionRule>();
         for (Method  method: methods){
             if (AnnotateMethod.isAnnotated(method)){
                 AnnotateMethod annotaedMethod = new AnnotateMethod(method,getSopedObject(ruleClass));
                 ProductionRule productionRule = new AnnotatedMethodToProductionRule(annotaedMethod);
                 methodsSet.add(productionRule);
             }
         }
         return methodsSet;
     }

    private InScopeOf<?> getSopedObject(Class<? extends InScopeOf<S>> ruleClass) {
        InScopeOf<S> inScopeOf = null;
        try {
            Constructor<? extends InScopeOf<S>> constructor = ruleClass.getConstructor();
            inScopeOf = constructor.newInstance();
            inScopeOf.setScope(scope);

        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return inScopeOf;  //To change body of created methods use File | Settings | File Templates.
    }


}
